/*
 *  +----------------------------------------------------------------------
 *  | sophon [ A FAST GAME FRAMEWORK ]
 *  +----------------------------------------------------------------------
 *  | Copyright (c) 2023-2029 All rights reserved.
 *  +----------------------------------------------------------------------
 *  | Licensed ( http:www.apache.org/licenses/LICENSE-2.0 )
 *  +----------------------------------------------------------------------
 *  | Author: jqiris <1920624985@qq.com>
 *  +----------------------------------------------------------------------
 */




use anyhow::Result;
use prost::Message;
use serde::{de::DeserializeOwned, Serialize};

use sophon::prelude::*;

pub trait Serializer<T> {
    fn get_name(&self) -> String;
    fn marshal(&self, msg: &T) -> Result<Vec<u8>>;
    fn unmarshal(&self, data: Vec<u8>, msg: &mut T) -> Result<()>;
}

pub struct ProtoSerializer {}

impl ProtoSerializer {
    pub fn new() -> ProtoSerializer {
        Self {}
    }
}

impl<T> Serializer<T> for ProtoSerializer
    where
        T: Message + Default,
{
    fn get_name(&self) -> String {
        "ProtoSerializer".into()
    }

    fn marshal(&self, msg: &T) -> Result<Vec<u8>> {
        Ok(msg.encode_to_vec())
    }

    fn unmarshal(&self, data: Vec<u8>, msg: &mut T) -> Result<()> {
        *msg = Message::decode(&*data)?;
        Ok(())
    }
}

pub struct JsonSerializer {}

impl JsonSerializer {
    pub fn new() -> JsonSerializer {
        Self {}
    }
}

impl<T> Serializer<T> for JsonSerializer
    where
        T: Serialize + DeserializeOwned,
{
    fn get_name(&self) -> String {
        "JsonSerializer".into()
    }

    fn marshal(&self, msg: &T) -> Result<Vec<u8>> {
        Ok(serde_json::to_string(msg)?.into())
    }

    fn unmarshal(&self, data: Vec<u8>, msg: &mut T) -> Result<()> {
        *msg = serde_json::from_slice(&*data)?;
        Ok(())
    }
}

fn main() {
    // let serializer = ProtoSerializer::new();
    // let s1 = Server {
    //     server_name: "testser".to_owned(),
    //     server_id: "welcome01".to_owned(),
    //     ..Default::default()
    // };
    // let res = serializer.marshal(&s1);
    // match res {
    //     Err(err) => eprintln!("marshal err:{}", err),
    //     Ok(data) => {
    //         let mut s2 = Server::default();
    //         if let Err(err) = serializer.unmarshal(data, &mut s2) {
    //             eprintln!("unmarshal err:{}", err);
    //         } else {
    //             println!("s2 is:{:?}", s2);
    //         }
    //     }
    // }

    let serializer = JsonSerializer::new();
    let s1 = Server {
        server_name: "testser".to_owned(),
        server_id: "welcome01".to_owned(),
        ..Default::default()
    };
    let res = serializer.marshal(&s1);
    match res {
        Err(err) => eprintln!("marshal err:{}", err),
        Ok(data) => {
            let mut s2 = Server::default();
            if let Err(err) = serializer.unmarshal(data, &mut s2) {
                eprintln!("unmarshal err:{}", err);
            } else {
                println!("s2 is:{:?}", s2);
            }
        }
    }
}
